package com.hongpu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hongpu.config.SecurityContextUtil;
import com.hongpu.domain.HpProjectWorkPay;
import com.hongpu.domain.HpProjectWorkPayList;
import com.hongpu.domain.HpProjectWorkPayListDetail;
import com.hongpu.domain.HpProjectWorkPayListReceivePayment;
import com.hongpu.dto.TotalReceiptsDto;
import com.hongpu.dto.UnpaidAmountDto;
import com.hongpu.enums.IncomeAndExpenditureTypesEnum;
import com.hongpu.enums.ItHasBeenInvoicedEnum;
import com.hongpu.enums.YesOrNoEnum;
import com.hongpu.mapper.HpProjectWorkPayListMapper;
import com.hongpu.mapper.HpProjectWorkPayMapper;
import com.hongpu.service.HpProjectWorkPayListDetailService;
import com.hongpu.service.HpProjectWorkPayListReceivePaymentService;
import com.hongpu.service.HpProjectWorkPayListService;
import com.hongpu.utils.ResultDto;
import com.hongpu.vo.HpProjectWorkPayListNewVo;
import com.hongpu.vo.HpProjectWorkPayListVo;
import com.hongpu.vo.InvoiceTaxAmountStatisticsVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Michael zhang
 * @description 针对表【hp_project_work_pay_list(项目的回款与支出明细)】的数据库操作Service实现
 * @createDate 2025-04-25 21:05:56
 */
@Service
public class HpProjectWorkPayListServiceImpl extends ServiceImpl<HpProjectWorkPayListMapper, HpProjectWorkPayList>
        implements HpProjectWorkPayListService {
    @Autowired
    HpProjectWorkPayListMapper baseMapper;
    @Autowired
    HpProjectWorkPayMapper hpProjectWorkPayMapper;
    @Autowired
    HpProjectWorkPayListDetailService hpProjectWorkPayListDetailService;
    @Autowired
    HpProjectWorkPayListReceivePaymentService hpProjectWorkPayListReceivePaymentService;

    /**
     * 分页
     *
     * @param page
     * @param projectName
     */
    @Override
    public IPage<HpProjectWorkPayListVo> selectPageInCome(IPage<?> page, String projectName) {
        return baseMapper.selectPageInCome(page, projectName);
    }

    @Override
    public IPage<HpProjectWorkPayListVo> selectPageExpenses(IPage<?> page, String projectName) {
        return baseMapper.selectPageExpenses(page, projectName);
    }

    @Override
    public IPage<HpProjectWorkPayListNewVo> selectPageExpenses2(IPage<?> page, String projectName) {
        IPage<HpProjectWorkPayListNewVo> resultPage = new Page<>();

        // 查询pay list数据
        IPage<HpProjectWorkPayListVo> payListVoPage = baseMapper.selectPageExpenses(page, projectName);
        List<HpProjectWorkPayListVo> records = payListVoPage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return resultPage;
        } else {
            resultPage.setCurrent(payListVoPage.getCurrent());
            resultPage.setPages(payListVoPage.getPages());
            resultPage.setTotal(payListVoPage.getTotal());
            List<HpProjectWorkPayListNewVo> payListDetails = new ArrayList<>();

            for (HpProjectWorkPayListVo payListVo : records) {
                HpProjectWorkPayListNewVo hpProjectWorkPayListNewVo = new HpProjectWorkPayListNewVo();
                // 装填支付汇总 pay list
                hpProjectWorkPayListNewVo.setId(payListVo.getId());
                hpProjectWorkPayListNewVo.setParentId(null);
                hpProjectWorkPayListNewVo.setPayUnit(payListVo.getPayUnit());
                hpProjectWorkPayListNewVo.setContractContent(payListVo.getContractContent());
                hpProjectWorkPayListNewVo.setAppointedTime(payListVo.getAppointedTime());
                hpProjectWorkPayListNewVo.setActualTime(payListVo.getActualTime());
                // 合同中约定的每次回款额，也就叫做合同金额
                BigDecimal contractAmount = payListVo.getContractAmount();
                hpProjectWorkPayListNewVo.setContractAmount(contractAmount);
                hpProjectWorkPayListNewVo.setPaid(payListVo.getPaid());
                hpProjectWorkPayListNewVo.setUnpaid(payListVo.getUnpaid());
                hpProjectWorkPayListNewVo.setRemark(payListVo.getRemark());
                hpProjectWorkPayListNewVo.setProjectWorkPayId(payListVo.getProjectWorkPayId());

                // 补充开票信息
                HpProjectWorkPayListDetail payListDetailInvoiceInfo = hpProjectWorkPayListDetailService.getInvoiceInfoByHpProjectWorkPayListId(payListVo.getId());
                if (payListDetailInvoiceInfo != null) {
                    // 是否开发票
                    Integer invoiceOrNot = payListDetailInvoiceInfo.getInvoiceOrNot();
                    hpProjectWorkPayListNewVo.setInvoiceOrNot(invoiceOrNot);
                    if(YesOrNoEnum.NO.getValue().equals(invoiceOrNot) || invoiceOrNot == null){
                        hpProjectWorkPayListNewVo.setItHasBeenInvoiced(ItHasBeenInvoicedEnum.NoInvoice.getValue());
                    }else {
                        hpProjectWorkPayListNewVo.setItHasBeenInvoiced(payListVo.getItHasBeenInvoiced());
                    }

                    hpProjectWorkPayListNewVo.setInvoiceType(payListDetailInvoiceInfo.getInvoiceType());
                    hpProjectWorkPayListNewVo.setInvoiceTaxRate(payListDetailInvoiceInfo.getInvoiceTaxRate());
                    // 不含税金额
                    BigDecimal amountBeforeTax = payListDetailInvoiceInfo.getAmountBeforeTax();
                    if(YesOrNoEnum.NO.getValue().equals(invoiceOrNot)){
                        //如果开发票，主数据显示不含税金额和税额，如果不开发票，不含税金额显示合同额；
                        amountBeforeTax =  contractAmount;
                    }
                    hpProjectWorkPayListNewVo.setAmountBeforeTax(amountBeforeTax);
                    hpProjectWorkPayListNewVo.setTheAmountOfTaxToBePaid(payListDetailInvoiceInfo.getTheAmountOfTaxToBePaid());

                }
                payListDetails.add(hpProjectWorkPayListNewVo);


                // 下面数据属于明细数据 pay list detail
                List<HpProjectWorkPayListDetail> payListDetailList = hpProjectWorkPayListDetailService.getByHpProjectWorkPayListId(payListVo.getId());
                for (HpProjectWorkPayListDetail payListDetail : payListDetailList) {
                    HpProjectWorkPayListNewVo detail = new HpProjectWorkPayListNewVo();
                    detail.setId(payListDetail.getId());
                    detail.setParentId(payListDetail.getHpProjectWorkPayListId());
                    detail.setPaid(payListDetail.getPaid());
                    detail.setActualTime(payListDetail.getPaidTime());
                    detail.setRemark(payListDetail.getRemark());
                    Integer invoiceOrNot = payListDetail.getInvoiceOrNot();
                    detail.setInvoiceOrNot(invoiceOrNot);
                    detail.setInvoiceType(payListDetail.getInvoiceType());
                    detail.setInvoiceTaxRate(payListDetail.getInvoiceTaxRate());
                    detail.setAmountBeforeTax(payListDetail.getAmountBeforeTax());
                    detail.setTheAmountOfTaxToBePaid(payListDetail.getTheAmountOfTaxToBePaid());
                    if(YesOrNoEnum.NO.getValue().equals(invoiceOrNot) || invoiceOrNot == null){
                        detail.setItHasBeenInvoiced(ItHasBeenInvoicedEnum.NoInvoice.getValue());
                    }else{
                        detail.setItHasBeenInvoiced(payListDetail.getItHasBeenInvoiced());
                    }
                    payListDetails.add(detail);

                }
            }
            resultPage.setRecords(payListDetails);
        }
        return resultPage;
    }

    /**
     * 新增数据之前，先根据projectWorkPayId清空数据
     *
     * @param projectWorkPayId
     */
    @Override
    public int deleteByProjectWorkPayId(Long projectWorkPayId) {
        return baseMapper.deleteByProjectWorkPayId(projectWorkPayId);
    }

    /**
     * 新增
     *
     * @param hpProjectWorkPayList
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(HpProjectWorkPay hpProjectWorkPay) {
        try {
            Long projectWorkPayId = hpProjectWorkPay.getId();
            // 根据projectWorkPayId清空历史数据
            deleteByProjectWorkPayId(projectWorkPayId);
            List<HpProjectWorkPayList> hpProjectWorkPayLists = hpProjectWorkPay.getHpProjectWorkPayLists();
            if (!CollectionUtils.isEmpty(hpProjectWorkPayLists)) {
                BigDecimal totalContractAmount = new BigDecimal(0);
                for (HpProjectWorkPayList hpProjectWorkPayList : hpProjectWorkPayLists) {
                    hpProjectWorkPayList.setProjectWorkPayId(projectWorkPayId);
                    totalContractAmount = totalContractAmount.add(hpProjectWorkPayList.getContractAmount());
                    save(hpProjectWorkPayList);
                    // hpProjectWorkPay的incomeAndExpenditureTypes值表示支付时： 向 hp_project_work_pay_list_detail 表中新增一条数据
                    if (IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue().equals(hpProjectWorkPay.getIncomeAndExpenditureTypes())) {
                        HpProjectWorkPayListDetail hpProjectWorkPayListDetail = new HpProjectWorkPayListDetail();
                        hpProjectWorkPayListDetail.setHpProjectWorkPayListId(hpProjectWorkPayList.getId());
                        hpProjectWorkPayListDetailService.save(hpProjectWorkPayListDetail);
                    }
                }
                // 将hpProjectWorkPayList中的contract_amount统计加和后，更新hp_project_work_pay中total_contract_amount
                hpProjectWorkPayMapper.updateTotalContractAmount(totalContractAmount, projectWorkPayId);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public List<HpProjectWorkPayList> getListByProjectWorkPayId(Long projectWorkPayId) {
        if (projectWorkPayId != null) {
            QueryWrapper<HpProjectWorkPayList> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("project_work_pay_id", projectWorkPayId);
            return baseMapper.selectList(queryWrapper);
        } else {
            return Collections.emptyList();
        }
    }

    @Override
    public List<HpProjectWorkPayList> selectHpProjectWorkPayListByProjectName(String projectName, String incomeAndExpenditureTypes) {
        if (StringUtils.isEmpty(projectName)) {
            return Collections.emptyList();
        } else {
            return baseMapper.selectHpProjectWorkPayListByProjectName(projectName, incomeAndExpenditureTypes);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDto updateProjectWorkPayListData(HpProjectWorkPayList hpProjectWorkPayList) {
        if (hpProjectWorkPayList == null) {
           return ResultDto.fail("系统没有收到待修改的数据");
        }
        /*
            业务：1、 根据传递过来的子表数据中projectWorkPayId查询所有子数据，然后统计所有子数据(不包含传递过来的子数据ID)合同额去修改主表total_contract_amount。
                 2、 子表所有字段数据都可修改。
        */
        Long projectWorkPayId = hpProjectWorkPayList.getProjectWorkPayId();
        Long id = hpProjectWorkPayList.getId();
        if (projectWorkPayId == null || id == null) {
            return ResultDto.fail();
        }
        try {
            // 应收金额汇总
            BigDecimal contractAmountSum = baseMapper.getContractAmountSum(projectWorkPayId, id);
            if (contractAmountSum == null) {
                contractAmountSum = new BigDecimal(0);
            }
            BigDecimal contractAmount = hpProjectWorkPayList.getContractAmount();
            if (contractAmount == null) {
                contractAmount = new BigDecimal(0);
            }
            BigDecimal totalContractAmount = contractAmountSum.add(contractAmount);
            Long payListId = hpProjectWorkPayList.getId();
            // 根据 payListId 判断该条数据是收入还是支出
            String incomeAndExpenditureTypes = hpProjectWorkPayMapper.getIncomeAndExpenditureTypes(payListId);
            if (incomeAndExpenditureTypes == null) {
                return ResultDto.fail("无法判断当前操作数据是收入还是支出");
            }
            if (IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue().equals(incomeAndExpenditureTypes)) {
                // 修改主表数据合同总金额
                hpProjectWorkPayMapper.updateTotalContractAmount2(totalContractAmount, projectWorkPayId);
            }
            // 更新 hp_project_work_pay_list
            if (IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue().equals(incomeAndExpenditureTypes)){
                baseMapper.updateById(hpProjectWorkPayList);
            }else if (IncomeAndExpenditureTypesEnum.INCOME.getValue().equals(incomeAndExpenditureTypes)){
           /*     // 已收款
                BigDecimal paid = hpProjectWorkPayList.getPaid();
                // 历史已收款
                BigDecimal historyPaid = BigDecimal.ZERO;
                BigDecimal queryHistoryPaid = baseMapper.totalPaid(projectWorkPayId,null);
                if(queryHistoryPaid != null){
                    historyPaid = queryHistoryPaid;
                }*/
/*                // 查询合同总金额
                BigDecimal queryTotalContractAmount = BigDecimal.ZERO;
                BigDecimal selectTtotalContractAmount = baseMapper.selectTotalContractAmount(projectWorkPayId);
                if (selectTtotalContractAmount != null) {
                    queryTotalContractAmount = selectTtotalContractAmount;
                }
                // 未收款
                BigDecimal unpaid = queryTotalContractAmount.subtract(paid);
                unpaid = unpaid.subtract(historyPaid);
                hpProjectWorkPayList.setUnpaid(unpaid);*/
                baseMapper.updateById(hpProjectWorkPayList);
            }
            if (IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue().equals(incomeAndExpenditureTypes)){
                // 更新unpaid字段的值
                BigDecimal unpaid = hpProjectWorkPayList.getContractAmount().subtract(hpProjectWorkPayList.getPaid() == null ? new BigDecimal(0) : hpProjectWorkPayList.getPaid());
                baseMapper.updateUnpaid(id, unpaid);
            }


            // 修改 hp_project_work_pay_list_detail 表中 开票信息:
            // 1、如果 HpProjectWorkPayList的ID为空且parentId不为空，则需要修改该条数据。

            Long parentId = hpProjectWorkPayList.getParentId();


            if (IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue().equals(incomeAndExpenditureTypes)) {
                if (payListId != null && parentId == null) {
                    // 是否需要开票
                    Integer invoiceOrNot = hpProjectWorkPayList.getInvoiceOrNot();
                    if (YesOrNoEnum.YES.getValue().equals(invoiceOrNot)) {
                        // 需要开票
                        BigDecimal payListDetailPaid = hpProjectWorkPayList.getPaid();
                        Integer invoiceType = hpProjectWorkPayList.getInvoiceType();
                        // 税率
                        BigDecimal invoiceTaxRate = hpProjectWorkPayList.getInvoiceTaxRate();

                        List<HpProjectWorkPayListDetail> payListDetailList = hpProjectWorkPayListDetailService.getByHpProjectWorkPayListId(payListId);
                        if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(payListDetailList)){
                            for (HpProjectWorkPayListDetail payListDetail : payListDetailList) {
                                // 将详情数据的税率设置为项目发票税率，及重新计算税额
                                BigDecimal paid = payListDetail.getPaid();
                                // 不含税金额 = hp_project_work_pay_list_detail表的支付金额 / (1+税率)
                                BigDecimal amountBeforeTax = paid.divide(new BigDecimal(1).add(invoiceTaxRate), 2, RoundingMode.HALF_UP);
                                //    税额= hp_project_work_pay_list_detail表的支付金额-不含税金额
                                BigDecimal theAmountOfTaxToBePaid = paid.subtract(amountBeforeTax);


                                HpProjectWorkPayListDetail hpProjectWorkPayListDetail = new HpProjectWorkPayListDetail();
                                hpProjectWorkPayListDetail.setId(payListDetail.getId());
                                hpProjectWorkPayListDetail.setHpProjectWorkPayListId(payListId);
                                hpProjectWorkPayListDetail.setPaid(payListDetailPaid);
                                hpProjectWorkPayListDetail.setInvoiceOrNot(invoiceOrNot);
                                hpProjectWorkPayListDetail.setInvoiceType(invoiceType);
                                hpProjectWorkPayListDetail.setInvoiceTaxRate(invoiceTaxRate);
                                hpProjectWorkPayListDetail.setAmountBeforeTax(amountBeforeTax);
                                hpProjectWorkPayListDetail.setTheAmountOfTaxToBePaid(theAmountOfTaxToBePaid);
                                hpProjectWorkPayListDetail.setRemark(hpProjectWorkPayList.getRemark());
                                hpProjectWorkPayListDetail.setItHasBeenInvoiced(hpProjectWorkPayList.getItHasBeenInvoiced());
                               // hpProjectWorkPayListDetailService.updateInvoice(hpProjectWorkPayListDetail);
                                hpProjectWorkPayListDetailService.updateInvoiceInfoById(hpProjectWorkPayListDetail);
                            }
                        }


                           /*
                            *   1、 修改主数据时，如果发票状态为已开或未开，则更新全部子数据发票状态为已开或未开。
                            *   2、 修改主数据时，如果发票状态为部分已开，子数据状态不做修改，只修改主数据。
                            * */


                        // 获取发票状态
                        Integer itHasBeenInvoiced = hpProjectWorkPayList.getItHasBeenInvoiced();
                        if (ItHasBeenInvoicedEnum.YES.getValue().equals(itHasBeenInvoiced) || ItHasBeenInvoicedEnum.NO.getValue().equals(itHasBeenInvoiced)) {
                            // 更新 hp_project_work_pay_list_detail 表中 it_has_been_invoiced 字段为 itHasBeenInvoiced
                            hpProjectWorkPayListDetailService.updateItHasBeenInvoiced(payListId, itHasBeenInvoiced);
                        } else if (ItHasBeenInvoicedEnum.OTHER.getValue().equals(itHasBeenInvoiced)) {
                            //修改主数据时，如果发票状态为部分已开，子数据状态不做修改，只修改主数据。 主数据的修改已经在  baseMapper.updateById(hpProjectWorkPayList); 中完成，这里不做任何操作。
                        }

                    } else {
                        // 不需要开票
                        // hp_project_work_pay_list 表中 it_has_been_invoiced 字段设置为 0
                        baseMapper.updateItHasBeenInvoiced(payListId, ItHasBeenInvoicedEnum.NO.getValue() , SecurityContextUtil.getUserId());
                        hpProjectWorkPayListDetailService.updateNotInvoice(payListId);
                    }
                }
            } else if (IncomeAndExpenditureTypesEnum.INCOME.getValue().equals(incomeAndExpenditureTypes)) {
                if (payListId != null && parentId == null) {
                    Integer invoiceOrNot = hpProjectWorkPayList.getInvoiceOrNot();
                    if (YesOrNoEnum.YES.getValue().equals(invoiceOrNot)) {
                        // 需要开票
                        HpProjectWorkPayListReceivePayment hpProjectWorkPayListReceivePayment = new HpProjectWorkPayListReceivePayment();
                        hpProjectWorkPayListReceivePayment.setHpProjectWorkPayListId(payListId);
                        hpProjectWorkPayListReceivePayment.setInvoiceOrNot(invoiceOrNot);
                        hpProjectWorkPayListReceivePayment.setInvoiceType(hpProjectWorkPayList.getInvoiceType());
                        hpProjectWorkPayListReceivePayment.setInvoiceTaxRate(hpProjectWorkPayList.getInvoiceTaxRate());
                        hpProjectWorkPayListReceivePayment.setAmountBeforeTax(hpProjectWorkPayList.getAmountBeforeTax());
                        hpProjectWorkPayListReceivePayment.setTheAmountOfTaxToBePaid(hpProjectWorkPayList.getTheAmountOfTaxToBePaid());
                        hpProjectWorkPayListReceivePayment.setItHasBeenInvoiced(hpProjectWorkPayList.getItHasBeenInvoiced());
                        hpProjectWorkPayListReceivePayment.setRemark(hpProjectWorkPayList.getRemark());
                        // 开票信息处理方式：1、首先判断是否有开票信息，有则更新，无则新增
                        List<HpProjectWorkPayListReceivePayment> receivePayments = hpProjectWorkPayListReceivePaymentService.getListByPayListId(payListId);
                        if(CollectionUtils.isEmpty(receivePayments)){
                            // 执行新增
                            hpProjectWorkPayListReceivePaymentService.save(hpProjectWorkPayListReceivePayment);
                        }else {
                            // 执行更新
                            hpProjectWorkPayListReceivePaymentService.invoice(hpProjectWorkPayListReceivePayment);
                        }
                    } else {
                        // 不需要开票 参数 payListId
                        hpProjectWorkPayListReceivePaymentService.invoiceNot(payListId);
                    }
                }
            }
            return ResultDto.ok();
        } catch (Exception e) {
            return ResultDto.fail(e.getLocalizedMessage());
        }
    }

    @Override
    public HpProjectWorkPay getHpProjectWorkPayByProjectWorkPayId(Long projectWorkPayId) {
        return baseMapper.getHpProjectWorkPayByProjectWorkPayId(projectWorkPayId);
    }

    /**
     * 明细数据删除
     *
     * @param id 明细数据ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(Long id) {
        // 1、根据明细数据ID查询明细数据
        // 2、根据明细数据的 projectWorkPayId 查询主表数据，
        // 3、 根据2的判断结果更新主表 total_contract_amount 字段的值
        try {
            HpProjectWorkPayList hpProjectWorkPayList = getById(id);
            if (hpProjectWorkPayList == null) {
                return false;
            }
            Long projectWorkPayId = hpProjectWorkPayList.getProjectWorkPayId();
            HpProjectWorkPay hpProjectWorkPay = hpProjectWorkPayMapper.selectById(projectWorkPayId);
            if (hpProjectWorkPay == null) {
                return false;
            }

            // 不需要删除的明细数据合计
            BigDecimal contractAmountSum = baseMapper.getContractAmountSum(projectWorkPayId, id);
            if (contractAmountSum == null) {
                contractAmountSum = new BigDecimal(0);
            }
            String incomeAndExpenditureTypes = hpProjectWorkPay.getIncomeAndExpenditureTypes();
            if (IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue().equals(incomeAndExpenditureTypes)){
                // 更新主表数据合同金额
                hpProjectWorkPayMapper.updateTotalContractAmount2(contractAmountSum, projectWorkPayId);
            }


            // 删除明细数据
            removeById(id);

            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<HpProjectWorkPayListVo> selectListInCome(String projectName) {
        return baseMapper.selectListInCome(projectName);
    }

    @Override
    public List<HpProjectWorkPayListVo> selectListExpenses(String projectName) {
        return baseMapper.selectListExpenses(projectName);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDto oneHpProjectWorkPayListAdd(HpProjectWorkPayList hpProjectWorkPayList) {
        try {
            // 当为支出时用的支付金额
            BigDecimal outPaid = hpProjectWorkPayList.getPaid();
            hpProjectWorkPayList.setPaid(BigDecimal.ZERO);
            if (hpProjectWorkPayList != null) {
                boolean save = save(hpProjectWorkPayList);
                if (save) {
                    Long projectWorkPayId = hpProjectWorkPayList.getProjectWorkPayId();
                    // 合同金额
                    BigDecimal contractAmount = hpProjectWorkPayList.getContractAmount();
                    if (projectWorkPayId != null && contractAmount != null) {
                        // 根据主表ID查询主表数据
                        HpProjectWorkPay hpProjectWorkPay = hpProjectWorkPayMapper.selectById(projectWorkPayId);
                        if (hpProjectWorkPay != null) {

                            String incomeAndExpenditureTypes = hpProjectWorkPay.getIncomeAndExpenditureTypes();
                            if (IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue().equals(incomeAndExpenditureTypes)) {
                                // 当为支出时，修改hp_project_work_pay_list中支付金额,哎~~~~~~~~~操蛋的逻辑
                                hpProjectWorkPayList.setPaid(outPaid);
                                updateById(hpProjectWorkPayList);

                                // 当为支出时 更新主表数据合同金额
                                hpProjectWorkPayMapper.updateTotalContractAmount(contractAmount, projectWorkPayId);
                            }

                            if (StringUtils.isEmpty(incomeAndExpenditureTypes)) {
                                ResultDto.fail("无法判断新增的数据属于收款还是支付");
                            }
                            // hpProjectWorkPay的incomeAndExpenditureTypes值表示支付时： 向 hp_project_work_pay_list_detail 表中新增一条数据
                            if (IncomeAndExpenditureTypesEnum.EXPENDITURE.getValue().equals(incomeAndExpenditureTypes)) {
                                HpProjectWorkPayListDetail hpProjectWorkPayListDetail = new HpProjectWorkPayListDetail();
                                hpProjectWorkPayListDetail.setHpProjectWorkPayListId(hpProjectWorkPayList.getId());
                                hpProjectWorkPayListDetail.setPaid(hpProjectWorkPayList.getPaid());
                                hpProjectWorkPayListDetail.setPaidTime(hpProjectWorkPayList.getActualTime());
                                hpProjectWorkPayListDetail.setRemark(hpProjectWorkPayList.getRemark());
                                hpProjectWorkPayListDetail.setItHasBeenInvoiced(hpProjectWorkPayList.getItHasBeenInvoiced());
                                // 发票税计算内容
                                Integer invoiceOrNot = hpProjectWorkPayList.getInvoiceOrNot();
                                hpProjectWorkPayListDetail.setInvoiceOrNot(invoiceOrNot);
                                if (YesOrNoEnum.YES.getValue().equals(invoiceOrNot)) {

                                    hpProjectWorkPayListDetail.setInvoiceType(hpProjectWorkPayList.getInvoiceType());
                                    // 税率
                                    BigDecimal invoiceTaxRate = hpProjectWorkPayList.getInvoiceTaxRate();
                                    if (invoiceTaxRate == null) {
                                        invoiceTaxRate = new BigDecimal(0);
                                    }
                                    hpProjectWorkPayListDetail.setInvoiceTaxRate(invoiceTaxRate);
                                    // 不含税金额 = 合同金额 / (1+税率)
                                    BigDecimal amountBeforeTax = contractAmount.divide(new BigDecimal(1).add(invoiceTaxRate), 2, RoundingMode.HALF_UP);
                                    hpProjectWorkPayListDetail.setAmountBeforeTax(amountBeforeTax);
                                    //    税额= 合同金额-不含税金额
                                    BigDecimal theAmountOfTaxToBePaid = contractAmount.subtract(amountBeforeTax);
                                    hpProjectWorkPayListDetail.setTheAmountOfTaxToBePaid(theAmountOfTaxToBePaid);
                                }
                                hpProjectWorkPayListDetailService.save(hpProjectWorkPayListDetail);
                            } else if (IncomeAndExpenditureTypesEnum.INCOME.getValue().equals(incomeAndExpenditureTypes)) {
                                // 当表示收入时： 向 hp_project_work_pay_list_receive_payment 表中新增一条开票数据
                                // 发票税计算内容
                                HpProjectWorkPayListReceivePayment hpProjectWorkPayListReceivePayment = new HpProjectWorkPayListReceivePayment();
                                Integer invoiceOrNot = hpProjectWorkPayList.getInvoiceOrNot();
                                hpProjectWorkPayListReceivePayment.setInvoiceOrNot(invoiceOrNot);
                                Long hpProjectWorkPayListId = hpProjectWorkPayList.getId();
                                hpProjectWorkPayListReceivePayment.setHpProjectWorkPayListId(hpProjectWorkPayListId);
                                if (YesOrNoEnum.YES.getValue().equals(invoiceOrNot)) {
                                    hpProjectWorkPayListReceivePayment.setInvoiceType(hpProjectWorkPayList.getInvoiceType());
                                    hpProjectWorkPayListReceivePayment.setInvoiceTaxRate(hpProjectWorkPayList.getInvoiceTaxRate());
                                    hpProjectWorkPayListReceivePayment.setAmountBeforeTax(hpProjectWorkPayList.getAmountBeforeTax());
                                    hpProjectWorkPayListReceivePayment.setTheAmountOfTaxToBePaid(hpProjectWorkPayList.getTheAmountOfTaxToBePaid());
                                    hpProjectWorkPayListReceivePayment.setItHasBeenInvoiced(hpProjectWorkPayList.getItHasBeenInvoiced());
                                }
                                hpProjectWorkPayListReceivePayment.setRemark(hpProjectWorkPayList.getRemark());
                                hpProjectWorkPayListReceivePaymentService.save(hpProjectWorkPayListReceivePayment);
                            }
                            return ResultDto.ok();
                        } else {
                            return ResultDto.fail("项目收款和支付信息不存在");
                        }
                    } else {
                        return ResultDto.fail("合同金额【contractAmount】不可以为空");
                    }
                }
            }
            return ResultDto.ok();
        } catch (Exception e) {
            return ResultDto.fail(e.getLocalizedMessage());
        }
    }

    /**
     * 收款合计
     *
     * @param projectName
     */
    @Override
    public TotalReceiptsDto totalReceipts(String incomeAndExpenditureTypes, String projectName) {
        TotalReceiptsDto totalReceiptsDto = baseMapper.totalReceipts(incomeAndExpenditureTypes, projectName);
        if (totalReceiptsDto == null) {
            totalReceiptsDto = new TotalReceiptsDto();
        }
        return totalReceiptsDto;
    }

    /**
     * 未收款金额
     *
     * @param unpaidAmountDto
     */
    @Override
    public ResultDto unpaidAmount(UnpaidAmountDto unpaidAmountDto) {
        try {
            Long projectWorkPayId = unpaidAmountDto.getProjectWorkPayId();
            /*Long id = unpaidAmountDto.getId();
            if(id ==  null){
                return ResultDto.fail("收款明细数据的ID不能为空");
            }*/
            if(projectWorkPayId == null){
                return  ResultDto.fail("projectWorkPayId参数不可以为空");
            }
            // 1、查询合同总金额
            BigDecimal totalContractAmount = BigDecimal.ZERO;
            BigDecimal queryTtotalContractAmount = baseMapper.selectTotalContractAmount(projectWorkPayId);
            if (queryTtotalContractAmount != null) {
                totalContractAmount = queryTtotalContractAmount;
            }
            // 2、查询已收款金额
            BigDecimal totalPaid = BigDecimal.ZERO;
            BigDecimal queryTotalPaid = baseMapper.totalPaid(projectWorkPayId,null);
            if (queryTotalPaid != null) {
                totalPaid = queryTotalPaid;
            }
            // 3、一共收款的金额
            totalPaid = totalPaid.add(unpaidAmountDto.getPaid() ==  null ? BigDecimal.ZERO : unpaidAmountDto.getPaid());
            // 4、计算未收款金额 = 总合同金额 - 已收款金额
            BigDecimal unpaid = totalContractAmount.subtract(totalPaid);
            // 给对象赋值
            unpaidAmountDto.setTotalContractAmount(totalContractAmount);
            unpaidAmountDto.setTotalPaid(totalPaid);
            unpaidAmountDto.setUnpaid(unpaid);
            return ResultDto.ok(unpaidAmountDto);
        } catch (Exception e) {
            return ResultDto.fail(e.getLocalizedMessage());
        }
    }

    @Override
    public ResultDto unpaidAmountForUpdate(UnpaidAmountDto unpaidAmountDto) {
        try {
            Long projectWorkPayId = unpaidAmountDto.getProjectWorkPayId();
            Long id = unpaidAmountDto.getId();
            if(id ==  null){
                return ResultDto.fail("收款明细数据的ID不能为空");
            }
            if(projectWorkPayId == null){
                return  ResultDto.fail("projectWorkPayId参数不可以为空");
            }
            // 1、查询合同总金额
            BigDecimal totalContractAmount = BigDecimal.ZERO;
            BigDecimal queryTtotalContractAmount = baseMapper.selectTotalContractAmount(projectWorkPayId);
            if (queryTtotalContractAmount != null) {
                totalContractAmount = queryTtotalContractAmount;
            }
            // 2、查询已收款金额
            BigDecimal totalPaid = BigDecimal.ZERO;
            BigDecimal queryTotalPaid = baseMapper.totalPaid(projectWorkPayId,id);
            if (queryTotalPaid != null) {
                totalPaid = queryTotalPaid;
            }
            // 3、一共收款的金额
            totalPaid = totalPaid.add(unpaidAmountDto.getPaid());
            // 4、计算未收款金额 = 总合同金额 - 已收款金额
            BigDecimal unpaid = totalContractAmount.subtract(totalPaid);
            // 给对象赋值
            unpaidAmountDto.setTotalContractAmount(totalContractAmount);
            unpaidAmountDto.setTotalPaid(totalPaid);
            unpaidAmountDto.setUnpaid(unpaid);
            return ResultDto.ok(unpaidAmountDto);
        } catch (Exception e) {
            return ResultDto.fail(e.getLocalizedMessage());
        }
    }

    /**
     * 税额统计
     *
     * @param projectWorkPayId          项目的收款或付款数据ID
     * @param incomeAndExpenditureTypes 项目收支类型：0收入 1支出
     * @return
     */
    @Override
    public List<InvoiceTaxAmountStatisticsVo> collectionTaxStatistics(Long projectWorkPayId, String incomeAndExpenditureTypes) {
        return baseMapper.collectionTaxStatistics(projectWorkPayId,incomeAndExpenditureTypes);
    }
}




